//
//  RZSystemSoundPlayer.m
//  RZIM
//
//  Created by reyzhang on 2021/8/16.
//

#import "RZSystemSoundPlayer.h"
#import <AVFoundation/AVFoundation.h>
#import "RZIMClient.h"

@interface RZSystemSoundPlayer ()
@property (atomic) BOOL isPlaying;   //原子操作
@property (nonatomic, assign) SystemSoundID soundId; //声音id
@property (nonatomic, copy) NSString *soundFilePath; //声音文件路径

@property (nonatomic, copy) NSString *targetId; //忽略响铃
@property (nonatomic, copy) RZSystemSoundPlayerCompletion completion;
@end



static void playSoundEnd(SystemSoundID mySSID, void *myself) {
    AudioServicesRemoveSystemSoundCompletion(mySSID);
    AudioServicesDisposeSystemSoundID(mySSID);

    //    CFRelease(myself);
    [RZSystemSoundPlayer defaultPlayer].isPlaying = NO;
}

@implementation RZSystemSoundPlayer

static RZSystemSoundPlayer *_player = nil;
+ (instancetype)defaultPlayer {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _player = [[[self class] alloc] init];
        _player.isPlaying = NO;
    });
    return _player;
}


/**
 设置系统声音的路径
 */
- (void)setSystemSoundPath:(NSString *)path {
    if (nil == path) {
        return;
    }
    _soundFilePath = path;
}



/**
 根据接收的消息 去播放声音
 */
- (void)playSoundByMessage:(RZMessage *)rcMessage completeBlock:(RZSystemSoundPlayerCompletion)completion {
    //如果是自己发送的，则不播放
    
    if ([rcMessage.gid isEqualToString:self.targetId]) {
        completion(NO);
    } else {
        self.completion = completion;
        [self needPlaySoundByMessage:rcMessage];
    }
}


/**
 * 设置忽略响铃的会话, 本质是会话的groupid
 */
- (void)setIgnoreSoundByConversationId:(NSString *)targetId; {
    self.targetId = targetId;
}


/**
 * 清除忽略响铃的会话
 */
- (void)resetIgnoreConversation {
    self.targetId = nil;
}


/**
 声音播放的核心代码
 */
- (void)needPlaySoundByMessage:(RZMessage *)rcMessage {
    if (RZSDKRunningMode_Background == [RZIMClient sharedClient].sdkRunningMode) {
        return;
    }


    if (self.isPlaying) {
        self.completion(NO);
        return;
    }

    AVAudioSession *audioSession = [AVAudioSession sharedInstance];

    NSError *err = nil;

#if __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_7_0
    //是否扬声器播放
    UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
    AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute, sizeof(audioRouteOverride), &audioRouteOverride);
#else
    [audioSession overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:nil];
#endif

    [audioSession setCategory:AVAudioSessionCategoryAmbient error:nil];

    [audioSession setActive:YES error:&err];
    

    if (nil != err) {
        NSLog(@"[RongIMKit]: Exception is thrown when setting audio session");
        self.completion(NO);
        return;
    }
    
    //如果没有指定声音路径
    if (nil == _soundFilePath) {
        // no redefined path, use the default
        _soundFilePath = [[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"RZIM.bundle"]
            stringByAppendingPathComponent:@"sms-received.caf"];
    }

    if (nil != _soundFilePath) {
        
        //根据声音文件路径 ，获取声音soundId
        OSStatus error =
            AudioServicesCreateSystemSoundID((__bridge CFURLRef)[NSURL fileURLWithPath:_soundFilePath], &_soundId);
        if (error != kAudioServicesNoError) { //获取的声音的时候，出现错误
            NSLog(@"Exception is thrown when creating system sound ID");
            self.completion(NO);
            return;
        }

        self.isPlaying = YES;
        if (RZ_IOS_SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"9.0")) {
            AudioServicesPlaySystemSoundWithCompletion(_soundId, ^{
                self.isPlaying = NO;
                self.completion(YES);
                return;
            });
        } else {
            AudioServicesPlaySystemSound(_soundId);
            AudioServicesAddSystemSoundCompletion(_soundId, NULL, NULL, playSoundEnd, NULL);
            self.completion(YES);
            return;
        }
    } else {
        NSLog(@"Not found the related sound resource file in RZIM.bundle");
        self.completion(NO);
        return;
    }
}


@end
